﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyBBS.Data.Models;
using MyBBS.Data.Interfaces;
using MyBBS.Data;
using MyBBS.Data.Filters;
using System.Configuration;

namespace MyBBS.Services
{
    public class PostService : IPostService
    {

        private readonly int pageSize = int.Parse(ConfigurationManager.AppSettings["PostPageSize"]);
        private readonly int commentSize = int.Parse(ConfigurationManager.AppSettings["CommentPageSize"]);

        private IPostRepository _postRepository;        

        /// <summary>
        /// Create a PostService based on the passed in repository
        /// </summary>
        /// <param name="postRepository">An IPostRepository</param>
        public PostService(IPostRepository postRepository)
        {
            this._postRepository = postRepository;
            if (_postRepository == null)
                throw new InvalidOperationException("PostRepository should not be null");
        }



        #region Get post list 
        
        /// <summary>
        /// Get a post list at the specified page
        /// </summary>
        /// <param name="page">Page No#</param>
        /// <returns>IList</returns>
        public IQueryable<Post> GetPosts()
        {
            return _postRepository.GetPosts();
        }

        /// <summary>
        /// Get a post list of specified Category
        /// </summary>
        /// <param name="categoryID">The Category ID</param>
        /// <returns>IList</returns>
        public IQueryable<Post> GetPostsByCategory(long categoryID)
        {
            return _postRepository.GetPosts()
                    .WithCategoryIDEquals(categoryID);
        }

        public IQueryable<Post> GetPostsByTag(long tagID)
        {
            return from pt in _postRepository.GetPostTags()
                   join p in _postRepository.GetPosts() on pt.PostID equals p.ID
                   where pt.TagID == tagID
                   select p;
                          
        }

        #endregion


        /// <summary>
        /// Get all categories
        /// </summary>
        /// <returns></returns>
        public IList<Category> GetCategories()
        {
            return _postRepository.GetCategories().ToList<MyBBS.Data.Models.Category>();
        }

        /// <summary>
        /// Get category by ID
        /// </summary>
        /// <param name="categoryID">Category ID</param>
        /// <returns>Category</returns>
        public Category GetCategoryByID(long categoryID)
        {
            return _postRepository.GetCategories().WithIDEquals(categoryID);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IList<Tag> GetPopularTags()
        {
            return _postRepository.GetPopularTags().ToList();
        }

        /// <summary>
        /// Add a new post
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        public long New(Post post)
        {
           return _postRepository.AddPost(post);
        }

        /// <summary>
        /// Kick a post and return kick count
        /// </summary>
        /// <param name="postID"></param>
        /// <returns></returns>
        public int Kick(Kick kick)
        {
            return _postRepository.Kick(kick);
        }

        #region Get post
        
        /// <summary>
        /// Get a post
        /// </summary>
        /// <param name="postID">Post's ID</param>
        /// <returns>Post</returns>
        public Post GetPostByID(long postID)
        {
            return _postRepository.GetPosts().WithIDEquals(postID).SingleOrDefault();
        }

        /// <summary>
        /// Get a post with it's comment info
        /// </summary>
        /// <param name="postID">Post's ID</param>
        /// <param name="commentPage">Comment's Page No#</param>
        /// <returns>Post</returns>
        //public Post GetPostByID(long postID, int? commentPage)
        //{
        //    Post post = _postRepository.GetPosts().WithIDEquals(postID).SingleOrDefault();

        //    //int commentCount = post.Comments.Count;

        //    //post.Comments = post.Comments.Skip((commentPage ?? 0) * commentSize).Take(commentSize).ToList();

        //    return post;
        //}
        #endregion

        #region Get/Add comment
        
        /// <summary>
        /// Add a new comment
        /// </summary>
        /// <param name="comment"></param>
        /// <returns></returns>
        public long SubmitComment(Comment comment)
        {
            return _postRepository.AddComment(comment);
        }

        /// <summary>
        /// Get a comment
        /// </summary>
        /// <param name="commentID"></param>
        /// <returns></returns>
        public Comment GetCommentByID(long commentID)
        {
            return _postRepository.GetComments().WithIDEquals(commentID);
        }
        #endregion
    }
}
